const xlsx = require("node-xlsx")
const { series, task } = require("gulp")
const { Command, Option } = require('commander')
const { color, log, red, green, cyan, cyanBright, yellowBG } = require('console-log-colors')
const fs = require('fs')
const path = require('path');

const program = new Command();
program
    .option('-i, --input <source>', 'transform excel folder input path')
    .option('-d, --dst <source>', 'transform excel folder output path')
    .addOption(new Option('-ot, --otype [value]', 'transform excel to ? type (json | lua)').choices(['json', 'lua']))
    .parse(process.argv)

function startTransform(done) {
    const options = program.opts();
    // check type
    let ot = options.otype;
    if (!ot)
        ot = 'json';

    if (!options.input) {
        console.error("[startTransform] options.dst is empty, we need a source dir");
        return;
    }

    let input = options.input;
    if (input[0] === '\"')
        input = input.substring(1, input.length - 1);

    let dest = options.dst;
    if (dest && dest[0] === '\"')
        dest = dest.substring(1, dest.length - 1);
    else if (!dest) 
        dest = input;

    console.log(green(input));
    if (!fs.existsSync(input)) {
        console.error("[startTransform] dst not exist");
        return;
    }
    var files = fs.readdirSync(input);
    for (let key in files) {
        let f = files[key];
        let ext = path.extname(f).split('.').pop()
        if (ext === 'xlsx') {
            parseExcel(`${input}\\${f}`, ot, dest);
        }
    }

    done();
}

/**
 * 
 * @param {string} file 
 * @param {string} type 
 */
function parseExcel(file, type, dest) {
    try {
        const workSheet = xlsx.parse(file);
        console.log(workSheet);

        if (workSheet.length <= 0) {
            console.log(red(`[parseExcel] type can't parse: ${file}`));
            return;
        }

        let sheet = workSheet[0];
        let length = sheet.data.length
        let datas = [];

        if (length <= 3) {
            console.log(red(`[parseExcel] type can't parse excel: ${file}`))
            return;
        }

        for (let i = 3; i < length; i++) {
            let propLen = sheet.data[0].length;
            let d = {};
            for (let j = 0; j < propLen; j++) {
                let property = sheet.data[1][j];

                // don't read "_" start data
                if (property[0] === '_')
                    continue;

                let rawD = sheet.data[i][j];
                let realD = null;
                switch (sheet.data[0][j]) {
                    case "int":
                        realD = rawD ? parseInt(rawD) : 0;
                        break;
                    case "float":
                        realD = rawD ? parseFloat(rawD) : 0;
                        break;
                    case "string":
                        realD = rawD ? rawD.toString() : "";
                        break;
                    case "str_array":
                        realD = rawD ? rawD.split('|') : [];
                        break;
                    case "float_array":
                        realD = rawD ? rawD.split('|') : [];
                        for (let x = 0; x < tmp.length; x++)
                            realD[x] = parseFloat(realD[x]);
                        break;
                    case "int_array":
                        realD = rawD ? rawD.split('|') : [];
                        for (let x = 0; x < realD.length; x++)
                            realD[x] = parseInt(realD[x]);
                        break;
                    case "bool":
                        realD = rawD ? true : false;
                        break;
                    default:
                        console.log(red(`[parseExcel] type can't parse: ${sheed.data[0][j]}`))
                        break;
                }
                d[property] = realD;
            }

            datas.push(d);
        }

        if (datas.length <= 0) {
            console.error(red(`[parseExcel] parseExcel failed: empty data`));
            return;
        }

        // get filename
        let filename = path.basename(file).split('.')[0];
        output(datas, type, dest, filename);
    }
    catch (e) {
        console.error(red("[parseExcel] " + e))
    }
}

/**
 * 
 * @param {array} datas 
 * @param {string} type 
 * @param {string} dest 
 */
function output(datas, type, dest, filename) {
    switch (type) {
        case 'json':
            let content = JSON.stringify(datas);
            fs.writeFileSync(`${dest}\\${filename}.json`, content, 'utf8');
            break;
        default:
            console.error(red(`[output] error type: ${type}`));
            break;
    }
}

/**
 * for test
 * @param {*} done 
 */
function test(done) {
    console.log(yellowBG("test ------------- "));
    done();
}

/**
 * for gulp forTest to excute method
 * */
task("forTest", (done) => {
    console.log(cyan("for task test"));
    const options = program.opts();
    if (!options.dst) {
        console.error("[parseExcel] options.dst is empty, we need a source dir");
        return;
    }

    const dst = options.dst;
    console.log(green(dst));

    done();
})

exports.default = series(startTransform, test);